//
//  WYWDeviceUtil.m
//  15WClient
//
//  Created by JinYong on 16/4/22.
//  Copyright © 2016年 15w. All rights reserved.
//

#import "WYWDeviceUtil.h"
#import "WYWUserDefault.h"

#import "KeychainItemWrapper.h"
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#import <mach/mach.h>
#import <mach/mach_host.h>
#include <ifaddrs.h>
#include <arpa/inet.h>

#import <CommonCrypto/CommonDigest.h>
#import <CoreTelephony/CTCarrier.h>
#import <CoreTelephony/CTTelephonyNetworkInfo.h>

#import <AdSupport/ASIdentifierManager.h>


#define kDeviceTokenKey                         @"wyw_device_token"
// Keychain
#define KEYCHAIN_GUID                           @"GUID"         // 替代UDID
#define USERDEFAULT_KEYCHAIN_GUID               @"WYW_GUID"     // 存入userdefault
#define KEYCHAIN_ACCOUNT                        @"Account"      // 用户名
#define KEYCHAIN_PASSWORD                       @"Password"     // 密码

#define kDeviceGUID                             @"device_guid"


#define STRINGHASVALUE(str)        (str && [str isKindOfClass:[NSString class]] && [str stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]].length > 0)


static NSString *keychain_guid = nil;

@implementation WYWDeviceUtil



+ (NSString *)macaddress {
    NSString *guid = [self GetGUIDString];
    return guid;
}

+ (NSString *)deviceGUID {
    NSString *guid = [[WYWUserDefault objectForKey:kDeviceGUID] copy];
    if (guid.length == 0) {
        NSString *aGuid = [[self GUIDString] copy];
        [WYWUserDefault setObject:aGuid forKey:kDeviceGUID];
        guid = [[WYWUserDefault objectForKey:kDeviceGUID] copy];
    }
    return guid;
}

+ (NSString *)device
{
    static NSString *modelString = nil;
    if (modelString) {
        return modelString;
    }
#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
    char *modelKey = "hw.machine";
#else
    char *modelKey = "hw.model";
#endif
    size_t size;
    sysctlbyname(modelKey, NULL, &size, NULL, 0);
    char *model = malloc(size);
    sysctlbyname(modelKey, model, &size, NULL, 0);
    modelString = [[NSString stringWithUTF8String:model] copy];
    free(model);
    return modelString;
}

+ (NSString *)GetGUIDString
{
    if (STRINGHASVALUE(keychain_guid)) {
        return keychain_guid;
    }
    KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:KEYCHAIN_GUID accessGroup:nil];
    
    //从keychain里取出GUID
    keychain_guid = [[wrapper objectForKey:(id)CFBridgingRelease(kSecValueData)] copy];
    if (STRINGHASVALUE(keychain_guid)) {
        return keychain_guid;
    }else{
        // 从文件读取
        keychain_guid = [[WYWUserDefault objectForKey:USERDEFAULT_KEYCHAIN_GUID] copy];
        if (STRINGHASVALUE(keychain_guid)) {
            return keychain_guid;
        }else{
            keychain_guid = [[self GUIDString] copy];
            [wrapper setObject:keychain_guid forKey:(__bridge id)kSecValueData];
            
            wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:KEYCHAIN_GUID accessGroup:nil];
            keychain_guid = [[wrapper objectForKey:(__bridge id)kSecValueData] copy];
            if (STRINGHASVALUE(keychain_guid)) {
                return keychain_guid;
            }else{
                keychain_guid = [[self GUIDString] copy];
                [WYWUserDefault setObject:keychain_guid forKey:USERDEFAULT_KEYCHAIN_GUID];
                return keychain_guid;
            }
        }
    }
}

+ (NSString*)GUIDString {
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    //    return (__bridge NSString *)string;
    return (NSString *)CFBridgingRelease(string);
}

+ (void)showAvailableMemory {
    vm_statistics_data_t vmStats;
    mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
    
    if(kernReturn != KERN_SUCCESS) return;
    
    double availableNum = ((vm_page_size * vmStats.free_count) / 1024.0) / 1024.0;
    NSLog(@"<<%.f M can be used>>",availableNum);
}

+ (NSString *)deviceIPAdress {
    NSString *address = @"an error occurred when obtaining ip address";
    struct ifaddrs *interfaces = NULL;
    struct ifaddrs *temp_addr = NULL;
    int success = 0;
    
    success = getifaddrs(&interfaces);
    
    if (success == 0) { // 0 表示获取成功
        temp_addr = interfaces;
        while (temp_addr != NULL) {
            if( temp_addr->ifa_addr->sa_family == AF_INET) {
                // Check if interface is en0 which is the wifi connection on the iPhone
                if ([[NSString stringWithUTF8String:temp_addr->ifa_name] isEqualToString:@"en0"]) {
                    // Get NSString from C String
                    address = [NSString stringWithUTF8String:inet_ntoa(((struct sockaddr_in *)temp_addr->ifa_addr)->sin_addr)];
                }
            }
            
            temp_addr = temp_addr->ifa_next;
        }
    }
    
    freeifaddrs(interfaces);
    return address;
}

+ (NSString *)md5:(NSString *)string{
    const char *str = [string UTF8String];
    unsigned char r[CC_MD5_DIGEST_LENGTH];
    CC_MD5(str, (CC_LONG)strlen(str), r);
    NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                          r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
    
    return filename;
}

+ (NSString*)data2jsonString:(id)object
{
    NSString *jsonString = nil;
    NSError *error;
    
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:object
                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                         error:&error];
    if (!jsonData) {
        NSLog(@"Got an error: %@", error);
    } else {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    return jsonString;
}

// 获取url参数
+ (NSString *) paramValueOfUrl:(NSString *) url withParam:(NSString *) param{
    
    NSError *error;
    NSString *regTags=[[NSString alloc] initWithFormat:@"(^|&|\\?)+%@=+([^&]*)(&|$)",param];
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:regTags
                                                                           options:NSRegularExpressionCaseInsensitive
                                                                             error:&error];
    
    // 执行匹配的过程
    NSArray *matches = [regex matchesInString:url
                                      options:0
                                        range:NSMakeRange(0, [url length])];
    for (NSTextCheckingResult *match in matches) {
        NSString *tagValue = [url substringWithRange:[match rangeAtIndex:2]];  // 分组2所对应的串
        return tagValue;
    }
    return nil;
}

// 获取中英文混排长度
+ (int)convertToInt:(NSString*)strtemp//判断中英混合的的字符串长度
{
    int strlength = 0;
    char* p = (char*)[strtemp cStringUsingEncoding:NSUnicodeStringEncoding];
    for (int i=0 ; i<[strtemp lengthOfBytesUsingEncoding:NSUnicodeStringEncoding] ;i++) {
        if (*p) {
            p++;
            strlength++;
        }
        else {
            p++;
        }
        
    }
    return strlength;
}


+ (NSString *)getMacAddress {
    int mib[6];
    size_t len;
    char *buf;
    unsigned char *ptr;
    struct if_msghdr *ifm;
    struct sockaddr_dl *sdl;
    
    mib[0] = CTL_NET;
    mib[1] = AF_ROUTE;
    mib[2] = 0;
    mib[3] = AF_LINK;
    mib[4] = NET_RT_IFLIST;
    
    if ((mib[5] = if_nametoindex("en0")) == 0) {
        printf("Error: if_nametoindex error/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
        printf("Error: sysctl, take 1/n");
        return NULL;
    }
    
    if ((buf = malloc(len)) == NULL) {
        printf("Could not allocate memory. error!/n");
        return NULL;
    }
    
    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
        free(buf);
        printf("Error: sysctl, take 2");
        return NULL;
    }
    
    ifm = (struct if_msghdr *)buf;
    sdl = (struct sockaddr_dl *)(ifm + 1);
    ptr = (unsigned char *)LLADDR(sdl);
    
     //MAC地址带冒号
     NSString *outstring = [NSString stringWithFormat:@"%02x:%02x:%02x:%02x:%02x:%02x", *ptr, *(ptr+1), *(ptr+2),
     *(ptr+3), *(ptr+4), *(ptr+5)];
    
    // MAC地址不带冒号
//    NSString *outstring = [NSString
//                           stringWithFormat:@"%02x%02x%02x%02x%02x%02x", *ptr, *(ptr + 1), *(ptr + 2), *(ptr + 3), *(ptr + 4), *(ptr + 5)];
    
    free(buf);
    
    return [outstring uppercaseString];
}

//获取idfa
+ (NSString *)getIDFA{
    return [ASIdentifierManager sharedManager].advertisingIdentifier.UUIDString;
}

@end
